<?php
/**
 * 目录管理
 * @since   2018-01-16
 */

namespace app\admin\controller;


use app\admin\model\AdminMenu;
use app\util\Tools;
use think\facade\Route;
use think\facade\Db;

class Menu extends Base {

    /**
     * @OA\Get(
     *   path="/admin/Menu/generate",
     *   tags={"菜单相关"},
     *   summary="菜单一键生成",
     *   @OA\Parameter(ref="#/components/parameters/AppClientVersion"),
     *   @OA\Parameter(ref="#/components/parameters/AppDeviceType"),
     *   @OA\Response(
     *     response=200,
     *     description="Success",
     *     @OA\JsonContent( type="array", @OA\Items(ref="#/components/schemas/response" ) )
     *   ),
     *   @OA\Response(response="500", description="服务器错误"),
     *   security={{"App-Login-Token": ""}}
     * )
     */
    public function generate() {
        $result = Route::getRuleList();
        $menuList = AdminMenu::column('id','url');
        $routeList = [];
        foreach ($result as $val){
            if(isset($val['option']['generateMenu'])){
                $item = $val['option']['generateMenu'];
                $item['route'] = $val['route'];
                $routeList[] = $item;
            }
        }
        $result = Tools::listToTree($routeList,'route','parent_route','children','/');
        $this->handleMenu($result,$menuList);
        $this->success('菜单已经生成完毕');
    }

    private function handleMenu(&$data,$menu,$parent = []) {
        foreach ($data as &$val){
            if(empty($val['title'])){
                $this->error("路由 $val[route] 缺少名称");
            }
            if(isset($val['hide']) && $val['hide'] == 0){
                if(empty($val['name'])){
                    $this->error("规则 $val[route] 缺少英文标识参数");
                }
                if(empty($val['path'])){
                    $this->error("规则 $val[route] 缺少前端路径参数");
                }
                if(empty($val['component']) && $val['parent_route'] != '/'){
                    $this->error("规则 $val[route] 缺少前端组件参数");
                }
            }
            $needInsertDB = true;//是否需要插入数据库
            if(isset($menu[$val['route']])){
                $needInsertDB = false;
            }
            if($needInsertDB){
                $item              = [];
                $item['url']       = $val['route'];
                $item['title']     = $val['title'];
                $item['fid']       = isset($menu[$val['parent_route']])?$menu[$val['parent_route']]:0;
                $item['sort']      = isset($val['sort'])?$val['sort']:0;
                $item['hide']      = isset($val['hide'])?$val['hide']:1;
                $item['icon']      = isset($val['icon'])?$val['icon']:'';
                $item['name']      = isset($val['name'])?$val['name']:null;
                $item['path']      = isset($val['path'])?$val['path']:null;
                $item['component'] = isset($val['component'])?$val['component']:null;
                $parentId = Db::name('admin_menu')->insertGetId($item);
                $menu[$item['url']] = $parentId;
            }
            if(isset($val['children'])){
                $this->handleMenu($val['children'],$menu,$parent);
            }
        }
    }

    /**
     * 获取菜单列表
     * @return array
     * @throws \think\exception\DbException
     * @author zhaoxiang <zhaoxiang051405@gmail.com>
     */
    public function index() {
        $list = (new AdminMenu)->where([])->order('sort', 'ASC')->select();
        $list = Tools::buildArrFromObj($list);
        $list = Tools::listToTree($list,'id','fid','children');
        $this->success('成功',[
            'list' => $list
        ]);
    }

    /**
     * 新增菜单
     * @return array
     */
    public function add() {
        $postData = $this->request->post();
        if ($postData['url']) {
            $postData['url'] = 'admin/' . $postData['url'];
        }
        if(isset($postData['hide']) && $postData['hide'] == 0){
            if(empty($postData['name'])){
                $this->error("缺少英文标识参数");
            }
            if(empty($postData['path'])){
                $this->error("缺少前端路径参数");
            }
            if(empty($postData['component'])){
                $this->error("缺少前端组件参数");
            }
        }
        $res = AdminMenu::create($postData);
        if ($res === false) {
            $this->error();
        } else {
            $this->success();
        }
    }

    /**
     * 菜单状态编辑
     * @return array
     */
    public function changeStatus() {
        $id = $this->request->get('id');
        $status = $this->request->get('status');
        $menu = AdminMenu::where(['id'=>$id])->find();
        if($status == 0){
            if(empty($menu['component']) || empty($menu['path']) || empty($menu['name'])){
                $this->error('该菜单前端显示的必要参数不全，不能更改为显示');
            }
        }
        $res = AdminMenu::update([
            'id'   => $id,
            'hide' => $status
        ]);
        if ($res === false) {
            $this->error();
        } else {
            $this->success();
        }
    }

    /**
     * 编辑菜单
     * @return array
     */
    public function edit() {
        $postData = $this->request->post();
        if ($postData['url']) {
            $postData['url'] = 'admin/' . $postData['url'];
        }
        if(isset($postData['hide'])){
            unset($postData['hide']);
        }
        $res = AdminMenu::update($postData);
        if ($res === false) {
            $this->error();
        } else {
            $this->success();
        }
    }

    /**
     * 删除菜单
     * @return array
     */
    public function del() {
        $id = $this->request->get('id');
        if (!$id) {
            $this->error('缺少必要参数');
        }
        $childNum = AdminMenu::where(['fid' => $id])->count();
        if ($childNum) {
            $this->error('当前菜单存在子菜单,不可以被删除!');
        } else {
            AdminMenu::destroy($id);

            $this->success();
        }
    }

}
